package com.songqi.common.web.request.handler;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.songqi.common.core.domain.R;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Locale;


/**
 * @author songqi(13776346982)
 */
@Slf4j
//@RestControllerAdvice
public class I18nHandler implements ResponseBodyAdvice<R> {

    @Value("${application.i18n-on-off:off}")
    private String i18nOnOff;

    @Resource
    private MessageSource messageSource;


    /**
     * 这个方法表示对于哪些请求要执行beforeBodyWrite，返回true执行，返回false不执行。
     * 访问swagger文档不需要调用beforeBodyWrite方法。解决访问swagger文档报错的问题。
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        boolean ignore = Arrays.stream(returnType.getDeclaringClass().getMethods()).anyMatch(method -> method.getDeclaredAnnotationsByType(IgnoreI18nHandler.class).length > 0);
        if(ignore){
            return false;
        }
        return !returnType.getDeclaringClass().getName().contains("springfox");
    }

    @Override
    public R beforeBodyWrite(R responseVO, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        if (responseVO == null) {
            return null;
        }
        String message = responseVO.getMsg();
        Object[] messageParams = responseVO.getMessageParams();
        message = parseMessage(message, messageParams, i18nOnOff);
        responseVO.setMsg(message);
        return responseVO;
    }

    private String parseMessage(String message, Object[] messageParams, String i18nOnOff) {
        String i18nMessage = "";
        try{
            if(StrUtil.equals(i18nOnOff, Constants.ON)){
                Locale locale = LocaleContextHolder.getLocale();
                if(messageParams != null && messageParams.length> 0){
                    i18nMessage = messageSource.getMessage(message, messageParams, locale);
                }else {
                    i18nMessage = messageSource.getMessage(message, null, locale);
                }
            }else {
                if(messageParams != null && messageParams.length> 0){
                    message = String.format(message, messageParams);
                }
            }
        } catch (NoSuchMessageException e ){
           log.error(e.getMessage(), e);
        }
        return StringUtils.isNotBlank(i18nMessage) ? i18nMessage : message;
    }

}
